import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Client_UDP extends JFrame{
    public  JTextField ipField;
    public  JTextField portField;
    public  JTextField fileField;
    public  JTextArea logArea;
   
    //创建Java GUI界面
    public JPanel set_GUI()
    {
        setTitle("File Client");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(5, 2));

        panel.add(new JLabel("Server IP:"));
        ipField = new JTextField("localhost");
        panel.add(ipField);

        panel.add(new JLabel("Server Port:"));
        portField = new JTextField("12345");
        panel.add(portField);

        panel.add(new JLabel("File to Send:"));
        fileField = new JTextField();
        panel.add(fileField);
        return panel;
    } 

    //添加 browse button
    public void browse_button(JPanel panel)
    {
        JButton browseButton = new JButton("Browse");
        panel.add(browseButton);
        browseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                int option = fileChooser.showOpenDialog(Client_UDP.this);
                if (option == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    fileField.setText(selectedFile.getAbsolutePath());
                }
            }
        });
    }

    //添加具有发送文件功能的发送按钮
    public void send_file_button(JPanel panel)
    {
        JButton sendButton = new JButton("Send File");
        panel.add(sendButton);
        /* panel.add(new JLabel("")); */
        panel.add(new JLabel("Log"));
        logArea = new JTextArea();
        logArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(logArea);

        JButton clearlogButton = new JButton("Clearlog");
        clearlogButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                logArea.setText("");
            }
        });
        panel.add(clearlogButton);


        add(panel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
        
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String serverIP = ipField.getText();
                int serverPort = Integer.parseInt(portField.getText());
                String filePath = fileField.getText();
                send_file(serverIP, serverPort, filePath);
            }
        });
    }

    //socket实现发送文件
    private void  send_file(String serverIP, int serverPort,String filePath)
    {
        new Thread(() -> {
                try (
                        DatagramSocket socket = new DatagramSocket();
                        FileInputStream fis = new FileInputStream(filePath);
                        ) {
                    InetAddress InserverIP = InetAddress.getByName(serverIP);
                    logArea.append("inserverip:"+InserverIP+"\n");
                    socket.connect(InserverIP, serverPort);
                    logArea.append("Connected to server.\n");
                    
                    File file = new File(filePath);
                    String fileName = file.getName();
                    byte[] fname = fileName.getBytes();
                    DatagramPacket fnamepacket = new DatagramPacket(fname, fname.length, InserverIP, serverPort);
                    socket.send(fnamepacket);
                    
                    
                    InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
                    BufferedReader br = new BufferedReader(isr);
                    /* byte[] buffer = new byte[4096];
                    int index = 0;
                    int data; */
                    String line ="";
                    System.out.println("line1: "+line);
                    String text= "";
                    int MAX_PACKET = 1024;
                    if(file.length() <= MAX_PACKET)
                    {
                        while((line = br.readLine())!= null)
                        {
                            line = line + "\n";
                            text = text + line;
                        }
                        DatagramPacket packet = new DatagramPacket(text.getBytes("UTF-8"),text.getBytes("UTF-8").length,InserverIP,serverPort);
                        socket.send(packet);
                        String eof = "EOF";
                        DatagramPacket eof_packet = new DatagramPacket(eof.getBytes("UTF-8"),eof.getBytes("UTF-8").length,InserverIP,serverPort);
                        socket.send(eof_packet);
                    }
                    else
                    {
                        while((line = br.readLine())!= null)
                        {
                            line = line + "\n";
                            System.out.println("line2: "+line);
                            text = text + line;
                            logArea.append("line length: "+ line.length());
                            if(text.length() > MAX_PACKET)
                            {
                                logArea.append("Packet length: "+ text.getBytes("UTF-8").length);
                                DatagramPacket packet = new DatagramPacket(text.getBytes("UTF-8"),text.getBytes("UTF-8").length,InserverIP,serverPort);
                                socket.send(packet);
                                text = "";
                            }
                        }
                        DatagramPacket packet = new DatagramPacket(text.getBytes("UTF-8"),text.getBytes("UTF-8").length,InserverIP,serverPort);
                        socket.send(packet);  
                        String eof = "EOF";
                        DatagramPacket eof_packet = new DatagramPacket(eof.getBytes(),eof.getBytes().length,InserverIP,serverPort);
                        socket.send(eof_packet);
                    }  

                    socket.close();
                    fis.close();
                    logArea.append("File " + fileName + " sent.\n");
                } catch (IOException e) {
                    logArea.append("Error: " + e.getMessage() + "\n");
                }
        }).start();
    }//实现socket输出流

public static  void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        Client_UDP client = new Client_UDP();
        client.setVisible(true);
        JPanel panel = client.set_GUI();
        client.browse_button(panel);
        client.send_file_button(panel);
    });
}
}
